package springdao.support;

import org.hibernate.SessionFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.util.Assert;
import springdao.DaoManager;

/**
 * Equal to build a {@link HibernateTransactionManager} bean like:</br>
 * 等同建立一個 {@link HibernateTransactionManager} 如:<br/>
 * &lt;bean class=&quot;org.springframework.orm.hibernate4.HibernateTransactionManager&quot;&gt;<br/>
 * &nbsp;&nbsp;&lt;property name=&quot;sessionFactory&quot; ref=&quot;sessionFactory&quot;/&gt;<br/>
 * &lt;/bean&gt;<br/>
 * If a {@link DaoManager}.{@link DaoManager#transactionManager()} not given or can't find a reference bean. then a 
 * DefaultHibernateTransactionManager given.<br/>
 * 如果{@link DaoManager}.{@link DaoManager#transactionManager()}未指定或找不到參考的Bean,則自動給定一個
 * DefaultHibernateTransactionManager.
 * @author Kent Yeh
 */
public class DefaultHibernateTransactionManager extends HibernateTransactionManager implements ApplicationContextAware {

    private static String DEFAULT_SESSION_FACTORY_NAME = "sessionFactory";
    private static final long serialVersionUID = 5371340602259158458L;
    private String defaultSessionFactoryName = DEFAULT_SESSION_FACTORY_NAME;
    private ApplicationContext context;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    public String getDefaultSessionFactoryName() {
        return defaultSessionFactoryName;
    }

    /**
     * set {@link SessionFactory}'s reference name.<br/>
     * 設定 {@link SessionFactory} 的參考名稱
     * @param defaultSessionFactoryName 
     */
    public void setDefaultSessionFactoryName(String defaultSessionFactoryName) {
        this.defaultSessionFactoryName = defaultSessionFactoryName;
    }

    @Override
    public void afterPropertiesSet() {
        if (getSessionFactory() == null) {
            Assert.hasText(defaultSessionFactoryName, "Must assign a sessionFactory or bean name references to a SessionFactory");
            SessionFactory sessionFactory = context.getBean(defaultSessionFactoryName, SessionFactory.class);
            Assert.notNull(sessionFactory, String.format("Can't find a SessionFactory with assoicated name \"%s\"", defaultSessionFactoryName));
            super.setSessionFactory(sessionFactory);
        }
        super.afterPropertiesSet();
    }
}
